package main

import (
	"context"
	favouriteserver "hertz_demo/kitex/favourite/kitex_gen/favouriteserver"
	"hertz_demo/orm/db"

	"gorm.io/gorm"
)

// FavouriteServiceImpl implements the last service interface defined in the IDL.
type FavouriteServiceImpl struct{}

// FavorVideo implements the FavouriteServiceImpl interface.
func (s *FavouriteServiceImpl) FavorVideo(ctx context.Context, req *favouriteserver.FavorVideoRequest) (resp *favouriteserver.FavorVideoResponse, err error) {
	// TODO: Your code here...
	resp = new(favouriteserver.FavorVideoResponse)
	relation := db.FavouriteRelation{
		UserId:  req.User.ID,
		VideoId: req.VideoId,
	}
	err = db.DB.Transaction(func(tx *gorm.DB) error {
		var relationId int64 = 0
		tx.Raw("select `id` from `favourite_relations` where `user_id`=? and `video_id`=? and is_del=false for update",
			req.User.ID, req.VideoId).Scan(&relationId)
		if relationId != 0 {
			return nil
		}
		if err := tx.Model(&db.FavouriteRelation{}).Create(&relation).Error; err != nil {
			return err
		}
		if err := tx.Model(&db.Video{}).Where("id=?", req.VideoId).Update("favourite_count", gorm.Expr("favourite_count + ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

// DisFavorVideo implements the FavouriteServiceImpl interface.
func (s *FavouriteServiceImpl) DisFavorVideo(ctx context.Context, req *favouriteserver.DisFavorVideoRequest) (resp *favouriteserver.DisFavorVideoResponse, err error) {
	// TODO: Your code here...
	resp = new(favouriteserver.DisFavorVideoResponse)
	err = db.DB.Transaction(func(tx *gorm.DB) error {
		var relationId int64 = 0
		tx.Raw("select `id` from `favourite_relations` where `user_id`=? and `video_id`=? and is_del=false for update",
			req.User.ID, req.VideoId).Scan(&relationId)
		if relationId == 0 {
			return nil
		}
		if err := tx.Model(&db.FavouriteRelation{}).Where("id=?", relationId).Update("is_del", true).Error; err != nil {
			return err
		}
		if err := tx.Model(&db.Video{}).Where("id=?", req.VideoId).Update("favourite_count", gorm.Expr("favourite_count - ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

// GetFavouriteList implements the FavouriteServiceImpl interface.
func (s *FavouriteServiceImpl) GetFavouriteList(ctx context.Context, req *favouriteserver.GetFavouriteListRequest) (resp *favouriteserver.GetFavouriteListResponse, err error) {
	// TODO: Your code here...
	resp = new(favouriteserver.GetFavouriteListResponse)
	// var resultList []models.Video
	var favouriteList []int64
	if err = db.DB.Model(&db.FavouriteRelation{}).Select("video_id").Where("user_id = ?", req.User.ID).Scan(favouriteList).Error; err != nil {
		return
	}
	var dbVideoList []db.Video
	if err = db.DB.Model(&db.Video{}).Find(&dbVideoList, favouriteList).Error; err != nil {
		return
	}
	for _, dbVideo := range dbVideoList {
		video := favouriteserver.Video{
			ID:             dbVideo.ID,
			Author:         req.User,
			Title:          dbVideo.Title,
			PlayUrl:        dbVideo.PlayUrl,
			CoverUrl:       dbVideo.CoverUrl,
			FavouriteCount: dbVideo.FavouriteCount,
			CommentCount:   dbVideo.CommentCount,
			IsFavourite:    true,
		}
		resp.ResultList = append(resp.ResultList, &video)
	}
	return
}
